using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;

namespace XnaDevRu.BulletX
{
    class MyNodeOverlapCallback : INodeOverlapCallback
    {
        StridingMeshInterface _meshInterface;
        ITriangleCallback _callback;
        Vector3[] _triangle = new Vector3[3];

        public MyNodeOverlapCallback(ITriangleCallback callback, StridingMeshInterface meshInterface)
        {
            _meshInterface = meshInterface;
            _callback = callback;
        }

        public void ProcessNode(OptimizedBvhNode node)
        {
            List<Vector3> verts;
            List<int> indicies;
            int numtriangles;

            _meshInterface.GetLockedReadOnlyVertexIndexBase(out verts, out indicies, out numtriangles, node.SubPart);
            Vector3 meshScaling = _meshInterface.Scaling;

            for (int j = 0; j < 3; j++)
            {
                _triangle[j] = verts[indicies[j + node.TriangleIndex * 3]] * meshScaling;
            }

            _callback.ProcessTriangle(_triangle, node.SubPart, node.TriangleIndex);
            _meshInterface.UnLockReadOnlyVertexBase(node.SubPart);
        }
    }

    public class BvhTriangleMeshShape : TriangleMeshShape
    {
        OptimizedBvh _bvh = new OptimizedBvh();

        public BvhTriangleMeshShape(StridingMeshInterface meshInterface) : base(meshInterface)
        {
            _bvh.Build(meshInterface);
        }

        public override void ProcessAllTriangles(ITriangleCallback callback, Vector3 aabbMin, Vector3 aabbMax)
        {
            MyNodeOverlapCallback myNodeCallback = new MyNodeOverlapCallback(callback, MeshInterface);
            _bvh.ReportAabbOverlappingNodex(myNodeCallback, aabbMin, aabbMax);
        }

        public override string Name
        {
            get
            {
                return "BvhTriangleMesh";
            }
        }
    }
}
